# -*- coding: utf-8 -*-

"""
 (c) 2023 - Copyright CTyunOS Inc

 Authors:
   youyifeng <youyf2@chinatelecom.cn>

"""

import json
import logging
from optparse import OptionParser

from cve_ease import activate_session, Scraper
from cve_ease.helper import one_instance_check
from cve_ease.models import CVE

logger = logging.getLogger('cve-ease')


def get_usage_str(usage):
    return usage + "\n(Specify the --help global option for a list of other help options)"


def handle_cve(gconfig, db_session, args):
    """[info] OpenEuler CVE info"""

    # one instance
    lock = one_instance_check(gconfig.LOCK_FILE_PATH)
    if lock:
        raise Exception(f"Another cve-ease already running")

    usage = "usage: %prog cve <options>"
    parser = OptionParser(usage=get_usage_str(usage))

    parser.add_option('-r', '--rawdata', dest='raw', action='store_true', default=False,
                      help='get cve cache and print raw data without write db')
    parser.add_option('-m', '--makecache', dest='makecache', action='store_true', default=False,
                      help='get cve cache')
    parser.add_option('-f', '--forcecache', dest='forcecache', action='store_true', default=False,
                      help='remove cve and update')
    parser.add_option('-l', '--list', dest='list', action='store_true', default=False,
                      help='list all cve info')
    parser.add_option('-t', '--total', dest='total', action='store_true', default=False,
                      help='get cve info statistics')
    parser.add_option('-v', '--verbose', dest='verbose', action='store_true', default=False,
                      help='show verbose output')

    (options, args) = parser.parse_args(args)

    session = activate_session(db_session, gconfig)
    logger.debug(" * active sql session")

    if options.makecache:
        total = session.query(CVE).count()
        scraper = Scraper()
        response = scraper.scrapyCVE(total)
        if "code" in response and response["code"] == 0:
            print(" * scrapy from OpenEuler done")
            totalCount = response["result"]["totalCount"]
            print(" * total record num:", totalCount)
            cveDatabaseList = response["result"]["cveDatabaseList"]
            cveDatabaseList = list({frozenset(item.items()): item for item in cveDatabaseList }.values())
            # recreate table
            #CVE.__table__.drop(db_session.get_engine())
            #CVE.__table__.create(db_session.get_engine())
            
            session.bulk_insert_mappings(CVE, [ cveData  for cveData in cveDatabaseList 
                                               if session.query(CVE).filter(CVE.id == cveData['id']).count()==0])
            session.commit()
            print(" * makecache done")
        else:
            print("! no usefull info found!")
    elif options.forcecache:
        total = session.query(CVE).count()
        scraper = Scraper()
        response = scraper.scrapyCVE()
        if "code" in response and response["code"] == 0:
            print(" * scrapy from OpenEuler done")
            totalCount = response["result"]["totalCount"]
            print(" * total record num:", totalCount)
            cveDatabaseList = response["result"]["cveDatabaseList"]
            cveDatabaseList = list({frozenset(item.items()): item for item in cveDatabaseList }.values())
            # recreate table
            CVE.__table__.drop(db_session.get_engine())
            CVE.__table__.create(db_session.get_engine())
            
            session.bulk_insert_mappings(CVE, cveDatabaseList)
            session.commit()
            print(" * makecache done")
        else:
            print("! no usefull info found!")
    elif options.total:
        total = session.query(CVE).count()
        print("cve total record :", total)
        if 0 == total:
            print(" WARNNING: no cve cache found! you should run 'cve-ease cve -m' to cache it.")
    elif options.list:
        cveDatabaseList = session.query(CVE).all()
        if 0 == len(cveDatabaseList):
            print(" WARNNING: no cve cache found! you should run 'cve-ease cve -m' to cache it.")
            return
        if options.verbose:
            CVE.pretty_output_title()
            for cve in cveDatabaseList:
                cve.simple_output()
        else:
            for cve in cveDatabaseList:
                cve.pretty_output()
    elif options.raw:
        scraper = Scraper()
        response = scraper.scrapyCVE()
        if "code" in response and response["code"] == 0:
            print(" * scrapy from OpenEuler done")
            totalCount = response["result"]["totalCount"]
            print(" * total record num:", totalCount)
            print(json.dumps(response, indent=4))
            print(" * makecache done")
        else:
            print("response error! no usefull info found!")
    else:
        parser.print_help()
